//
// Created by baigui on 2021/10/24.
//

#ifndef SIMPLE_PLAYER_TS_PID_H
#define SIMPLE_PLAYER_TS_PID_H

#include <FFMPEGDemux.h>
#include "stdint.h"

#define TS_FEC_PACKET_SIZE 204
#define TS_DVHS_PACKET_SIZE 192
#define TS_PACKET_SIZE 188
#define TS_MAX_PACKET_SIZE 204

#define NB_PID_MAX 8192
#define MAX_SECTION_SIZE 4096

/* pids */
#define PAT_PID                 0x0000
#define SDT_PID                 0x0011

/* table ids */
#define PAT_TID   0x00
#define PMT_TID   0x02
#define M4OD_TID  0x05
#define SDT_TID   0x42

#define STREAM_TYPE_VIDEO_MPEG1     0x01
#define STREAM_TYPE_VIDEO_MPEG2     0x02
#define STREAM_TYPE_AUDIO_MPEG1     0x03
#define STREAM_TYPE_AUDIO_MPEG2     0x04
#define STREAM_TYPE_PRIVATE_SECTION 0x05
#define STREAM_TYPE_PRIVATE_DATA    0x06
#define STREAM_TYPE_AUDIO_AAC       0x0f
#define STREAM_TYPE_AUDIO_AAC_LATM  0x11
#define STREAM_TYPE_VIDEO_MPEG4     0x10
#define STREAM_TYPE_METADATA        0x15
#define STREAM_TYPE_VIDEO_H264      0x1b
#define STREAM_TYPE_VIDEO_HEVC      0x24
#define STREAM_TYPE_VIDEO_CAVS      0x42
#define STREAM_TYPE_VIDEO_VC1       0xea
#define STREAM_TYPE_VIDEO_DIRAC     0xd1

#define STREAM_TYPE_AUDIO_AC3       0x81
#define STREAM_TYPE_AUDIO_DTS       0x82
#define STREAM_TYPE_AUDIO_TRUEHD    0x83
#define STREAM_TYPE_AUDIO_EAC3      0x87



typedef struct StreamType {
    uint32_t stream_type;
    enum AVMediaType codec_type;
    enum AVCodecID codec_id;
} StreamType;

static const StreamType ISO_types[] = {
        { 0x01, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
        { 0x02, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO },
        { 0x03, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3        },
        { 0x04, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3        },
        { 0x0f, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC        },
        { 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4      },
        /* Makito encoder sets stream type 0x11 for AAC,
         * so auto-detect LOAS/LATM instead of hardcoding it. */
#if !CONFIG_LOAS_DEMUXER
        { 0x11, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC_LATM   }, /* LATM syntax */
#endif
        { 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264       },
        { 0x1c, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC        },
        { 0x20, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264       },
        { 0x21, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_JPEG2000   },
        { 0x24, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC       },
        { 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS       },
        { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC      },
        { 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1        },
        { 0 },
};

static const StreamType HDMV_types[] = {
        { 0x80, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_PCM_BLURAY        },
        { 0x81, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_AC3               },
        { 0x82, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS               },
        { 0x83, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_TRUEHD            },
        { 0x84, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_EAC3              },
        { 0x85, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS               }, /* DTS HD */
        { 0x86, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS               }, /* DTS HD MASTER*/
        { 0xa1, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_EAC3              }, /* E-AC3 Secondary Audio */
        { 0xa2, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS               }, /* DTS Express Secondary Audio */
        { 0x90, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_PGS_SUBTITLE },
        { 0x92, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_TEXT_SUBTITLE },
        { 0 },
};

/* SCTE types */
static const StreamType SCTE_types[] = {
        { 0x86, AVMEDIA_TYPE_DATA,  AV_CODEC_ID_SCTE_35    },
        { 0 },
};

/* ATSC ? */
static const StreamType MISC_types[] = {
        { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 },
        { 0x8a, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS },
        { 0 },
};

static const StreamType REGD_types[] = {
        { MKTAG('d', 'r', 'a', 'c'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC },
        { MKTAG('A', 'C', '-', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3   },
        { MKTAG('B', 'S', 'S', 'D'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_S302M },
        { MKTAG('D', 'T', 'S', '1'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS   },
        { MKTAG('D', 'T', 'S', '2'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS   },
        { MKTAG('D', 'T', 'S', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS   },
        { MKTAG('E', 'A', 'C', '3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3  },
        { MKTAG('H', 'E', 'V', 'C'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_HEVC  },
        { MKTAG('K', 'L', 'V', 'A'), AVMEDIA_TYPE_DATA,  AV_CODEC_ID_SMPTE_KLV },
        { MKTAG('I', 'D', '3', ' '), AVMEDIA_TYPE_DATA,  AV_CODEC_ID_TIMED_ID3 },
        { MKTAG('V', 'C', '-', '1'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1   },
        { MKTAG('O', 'p', 'u', 's'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_OPUS  },
        { 0 },
};

static const StreamType METADATA_types[] = {
        { MKTAG('K','L','V','A'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_KLV },
        { MKTAG('I','D','3',' '), AVMEDIA_TYPE_DATA, AV_CODEC_ID_TIMED_ID3 },
        { 0 },
};

/* descriptor present */
static const StreamType DESC_types[] = {
        { 0x6a, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_AC3          }, /* AC-3 descriptor */
        { 0x7a, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_EAC3         }, /* E-AC-3 descriptor */
        { 0x7b, AVMEDIA_TYPE_AUDIO,    AV_CODEC_ID_DTS          },
        { 0x56, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_TELETEXT },
        { 0x59, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_SUBTITLE }, /* subtitling descriptor */
        { 0 },
};

static const StreamType* mpegts_find_stream_type(
                                    uint32_t stream_type,
                                    const StreamType *types)
{
    for (; types->stream_type; types++)
        if (stream_type == types->stream_type) {
            return types;
        }

    return nullptr;
}




#endif //SIMPLE_PLAYER_TS_PID_H
